package com.dongjiantong.farmrecords.serviceImpl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.dongjiantong.biz.model.Stables;
import com.dongjiantong.biz.service.FarmStockService;
import com.dongjiantong.biz.service.StablesService;
import com.dongjiantong.common.exceptions.HttpCode;
import com.dongjiantong.common.exceptions.OPServerException;
import com.dongjiantong.common.utils.JsonUtil;
import com.dongjiantong.common.utils.ReportNumberMakerUtil;
import com.dongjiantong.common.web.sso.LoginInfo;
import com.dongjiantong.common.web.util.UserUtil;
import com.dongjiantong.farmrecords.enums.FarmRecordsFileEnum;
import com.dongjiantong.farmrecords.enums.FarmRecordsNumberStatus;
import com.dongjiantong.farmrecords.mapper.FarmRecordsFileMapper;
import com.dongjiantong.farmrecords.mapper.FarmRecordsProductionMapper;
import com.dongjiantong.farmrecords.model.FarmRecordsFile;
import com.dongjiantong.farmrecords.model.FarmRecordsHarmlesses;
import com.dongjiantong.farmrecords.model.FarmRecordsProduction;
import com.dongjiantong.farmrecords.service.FarmRecordsHarmlessesService;
import com.dongjiantong.farmrecords.service.FarmRecordsProductionService;
import com.dongjiantong.mybatis.ServiceMybatis;
import com.dongjiantong.sys.service.SysLogsService;
import com.dongjiantong.user.enums.FarmsEnum;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 生产中心-生产记录
 */
@Slf4j
@Service(version = "1.0.0")
public class FarmRecordsProductionServiceImpl extends ServiceMybatis<FarmRecordsProduction> implements FarmRecordsProductionService {

    @Resource
    private FarmRecordsProductionMapper farmRecordsProductionMapper;
    @Resource
    private FarmRecordsFileMapper farmRecordsFileMapper;

    @Resource
    public FarmRecordsHarmlessesService farmRecordsHarmlessesService;

    @Reference(version = "1.0.0")
    public SysLogsService sysLogsService;
    @Reference(version = "1.0.0")
    public StablesService stablesService;
    @Reference(version = "1.0.0")
    public FarmStockService farmStockService;


    @Override
    public PageInfo<FarmRecordsProduction> selectByMap(Integer pageNum, Integer pageSize, Map map) {
        try {
            if (farmRecordsProductionMapper == null){
                throw new OPServerException("farmRecordsProductionMapper 为null,请检查");
            }
            PageHelper.startPage(pageNum,pageSize);
            //查询有效单据
            map.put("delete_flag", FarmRecordsNumberStatus.EFFECTIVE.getCode());

            //查询已启用的养殖场
            map.put("farmStatus", FarmsEnum.status_true.getCode());
            List<FarmRecordsProduction> list = farmRecordsProductionMapper.selectByMap(map);
            if (list.size() > 0){
                this.setPicOrVideoList(list);
            }
            return new PageInfo<FarmRecordsProduction>(list);
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            throw new OPServerException(HttpCode.INTERNAL_SERVER_ERROR,HttpCode.INTERNAL_SERVER_ERROR.getMessage());
        }
    }

    /**
     * 设置关联信息(视频,图片)
     * @param farmRecordsProductionList
     */
    public void setPicOrVideoList(List<FarmRecordsProduction> farmRecordsProductionList){
        if (farmRecordsFileMapper == null){
            throw new OPServerException("farmRecordsFileMapper 为null,请检查");
        }
        List<Long> ids = farmRecordsProductionList.stream().map(farmRecordsProduction -> farmRecordsProduction.getId()).collect(Collectors.toList());

        List<Integer> type2List = Lists.newArrayList(FarmRecordsFileEnum.PHOTO.getCode(),FarmRecordsFileEnum.VIDEO.getCode());

        Map map = Maps.newHashMap();
        map.put("relevanceIds",ids);
        map.put("listType2",type2List);
        map.put("type1",FarmRecordsFileEnum.PRODUCTION.getCode());
        //查询对应的图片,视频
        List<FarmRecordsFile> farmRecordsFileList = farmRecordsFileMapper.selectPicOrVideoListByRelevanceIds(map);

        if (farmRecordsFileList.size() > 0){
            for (FarmRecordsProduction farmRecordsProduction : farmRecordsProductionList){
               this.setPicOrVideoByObj(farmRecordsProduction,farmRecordsFileList);
            }
        }
    }

    public FarmRecordsProduction setPicOrVideoByObj(FarmRecordsProduction farmRecordsProduction,List<FarmRecordsFile> farmRecordsFileList){
        List<String> picList = Lists.newArrayList();
        List<String> videoList = Lists.newArrayList();
        for (FarmRecordsFile farmRecordsFile : farmRecordsFileList){
            if ((farmRecordsProduction.getId()).equals(farmRecordsFile.getRelevance_id())){
                //获取图片
                if ((FarmRecordsFileEnum.PHOTO.getCode()).equals(farmRecordsFile.getType2())){
                    picList.add(farmRecordsFile.getAddress());
                }
                //获取视频
                if ((FarmRecordsFileEnum.VIDEO.getCode()).equals(farmRecordsFile.getType2())){
                    videoList.add(farmRecordsFile.getAddress());
                }
            }
        }
        //设置图片
        if (picList.size() > 0){
            farmRecordsProduction.setPicList(picList);
        }
        //设置视频
        if (videoList.size() > 0){
            farmRecordsProduction.setVideoList(videoList);
        }
        return farmRecordsProduction;
    }

    /**
     * 新增单据生产记录单据
     * @param farmRecordsProduction
     * @param toStatus  更新到状态
     * @param isFrom (无害化的标志 1表示生产死淘过来的，提交后不用做生产死淘，2的话用户自己做的，需要死淘单)
     * @return
     */
    @Override
    public Map<String,Object> createOne(LoginInfo loginInfo,FarmRecordsProduction farmRecordsProduction, Integer toStatus, Integer isFrom) {
        Map<String,Object> result = Maps.newHashMap();

        try {
            if (farmRecordsProductionMapper == null){
                throw new OPServerException("farmRecordsProductionMapper 为null,请检查");
            }
            //操作前的数据
            String jsonBefore = JsonUtil.toJsonString(farmRecordsProduction);

            Integer fromStatus = farmRecordsProduction.getStatus();

            //todo 生成单据号
            //单据生成规则暂未定(此处为测试)
            String prefix = "SSC";
            prefix = ReportNumberMakerUtil.createPrefix(prefix,loginInfo.getProvinceId(),loginInfo.getCityId(),loginInfo.getRegionId());
            String maxNumber = farmRecordsProductionMapper.findMaxNumber(prefix);
            String number = ReportNumberMakerUtil.create(prefix,maxNumber);
            farmRecordsProduction.setNumber(number);

            //地区信息
            farmRecordsProduction.setProvince_id(loginInfo.getProvinceId());
            farmRecordsProduction.setCity_id(loginInfo.getCityId());
            farmRecordsProduction.setRegion_id(loginInfo.getRegionId());
            farmRecordsProduction.setStreet_id(loginInfo.getStreetId());
            farmRecordsProduction.setVillage_id(loginInfo.getVillageId());

            //创建单据信息默认有效
            farmRecordsProduction.setDelete_flag(FarmRecordsNumberStatus.EFFECTIVE.getCode());

            //todo 根据单据状态区分暂存提交
            if (fromStatus == 0 && toStatus == null){
                //直接暂存
                farmRecordsProductionMapper.createOne(farmRecordsProduction);
            }else if (!fromStatus.equals(toStatus) && FarmRecordsNumberStatus.SUBMIT.getCode().equals(toStatus)){
                //直接提交
                farmRecordsProduction.setStatus(toStatus);
                farmRecordsProductionMapper.createOne(farmRecordsProduction);
                //todo 需要对存栏作出改变

                //todo 改变存栏信息
                if (farmRecordsProduction.getStable_id() != null){
                    //1. 更改栏舍信息
                    Stables stablesBefore = stablesService.selectByPrimaryKey(farmRecordsProduction.getStable_id());

                    if (stablesBefore != null) {

                        stablesBefore.setQuantity(farmRecordsProduction.getChange_quantity());
                        stablesBefore.setUpdated_at(new Date());

                        stablesService.updateSC(stablesBefore);
                    }
                }
                //2. 更改存栏量
                Map<String,Object> map = Maps.newHashMap();
                map.put("farmId",farmRecordsProduction.getFarm_id());
                map.put("changeQuantity",farmRecordsProduction.getChange_quantity());
                farmStockService.updateByFarmId(map);

                //todo 判断死淘 (做无害化记录单据)
                if (farmRecordsProduction.getDeath_quantity() != null && farmRecordsProduction.getDeath_quantity() !=0 && isFrom != 2) {
                    //todo 新建一单无害化记录 (非集中处理无害化记录)
                    FarmRecordsHarmlesses farmrecordsHarmlesses = this.createHarmlessesNoCenter(loginInfo,farmRecordsProduction,isFrom);

                    farmRecordsHarmlessesService.createOne(loginInfo, farmrecordsHarmlesses,null,1);

                    if (farmrecordsHarmlesses.getId() != null) {
                        result.put("harmlessId", farmrecordsHarmlesses.getId());
                    }
                }
            }

            if (farmRecordsProduction.getId() != null && farmRecordsProduction.getId() != 0) {
                result.put("receiptId",farmRecordsProduction.getId());
            }

            /*//todo 生成政府操作记录
           //操作后的数据
            String jsonAfter = JsonUtil.toJsonString(farmRecordsProduction);
            sysLogsService.createLogs(LogsEnum.ADD,
                    FarmRecordsTableEnum.FARM_RECORDS_PRODUCTION.getTableName(),
                    farmRecordsProduction.getId().toString(),
                    jsonBefore,
                    jsonAfter,
                    loginInfo.getId());*/

            return result;
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            throw new OPServerException(HttpCode.INTERNAL_SERVER_ERROR,HttpCode.INTERNAL_SERVER_ERROR.getMessage());
        }
    }


    /**
     * 更新一条记录 (根据id或者number)
     * @param farmRecordsProduction
     * @param toStatus
     * @return  boolean (更新成功返回true 反之返回false)
     */
    @Override
    public Integer updateByIdOrNumber(FarmRecordsProduction farmRecordsProduction,Integer toStatus) {
        try {
            if (farmRecordsProductionMapper == null){
                throw new OPServerException("farmRecordsProductionMapper 为null,请检查");
            }

            //获取登录人
            Long userId = UserUtil.getUserId();
            //操作前的数据
            String jsonBefore = JsonUtil.toJsonString(farmRecordsProduction);

            //todo 更新记录
            farmRecordsProduction.setUpdated_at(new Date());
            farmRecordsProduction.setStatus(toStatus);
            Integer con = farmRecordsProductionMapper.updateByPrimaryKeySelective(farmRecordsProduction);

            //todo 改变存栏信息
            if (farmRecordsProduction.getStable_id() != null){
                //1. 更改栏舍信息
                Stables stablesBefore = stablesService.selectByPrimaryKey(farmRecordsProduction.getStable_id());

                Stables stables = new Stables();
                stables.setId(farmRecordsProduction.getId());
                stables.setQuantity(stablesBefore.getQuantity() + farmRecordsProduction.getChange_quantity());
                stablesService.updateSC(stables);
            }
            //2. 更改存栏量
            Map<String,Object> map = Maps.newHashMap();
            map.put("farmId",farmRecordsProduction.getFarm_id());
            map.put("changeQuantity",farmRecordsProduction.getChange_quantity());
            farmStockService.updateByFarmId(map);

            /*//todo 生成政府操作记录
            //操作后的数据
            String jsonAfter = JsonUtil.toJsonString(farmRecordsProduction);
            sysLogsService.createLogs(LogsEnum.UPDATE,
                    FarmRecordsTableEnum.FARM_RECORDS_PRODUCTION.getTableName(),
                    farmRecordsProduction.getId().toString(),
                    jsonBefore,
                    jsonAfter,
                    userId);*/

            return con;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new OPServerException(HttpCode.DATA_UPDATE_FAIL,HttpCode.DATA_UPDATE_FAIL.getMessage());
        }
    }

    /**
     * 根据主键id删除一条记录
     * @param id
     * @return
     */
    @Override
    public boolean deleteById(Long id) {

        FarmRecordsProduction production = farmRecordsProductionMapper.selectByPrimaryKey(id);
        //操作前的数据
        String jsonBefore = JsonUtil.toJsonString(production);
        //获取登陆人
        Long userId = UserUtil.getUserId();

        FarmRecordsProduction farmRecordsProduction = new FarmRecordsProduction();
        farmRecordsProduction.setId(id);
        farmRecordsProduction.setDelete_flag(FarmRecordsNumberStatus.INVALID.getCode());
        farmRecordsProduction.setUpdated_at(new Date());
        Integer con = farmRecordsProductionMapper.updateByPrimaryKeySelective(farmRecordsProduction);

        //todo 改变存栏信息
        if (farmRecordsProduction.getStable_id() != null){
            //1. 更改栏舍信息
            Stables stablesBefore = stablesService.selectByPrimaryKey(farmRecordsProduction.getStable_id());

            Stables stables = new Stables();
            stables.setId(farmRecordsProduction.getId());
            //还原单据之前对存栏总数量的改动数量
            stables.setQuantity(stablesBefore.getQuantity() - farmRecordsProduction.getChange_quantity());
            stablesService.updateSC(stables);
        }
        //2. 更改存栏信息
        Map<String,Object> map = Maps.newHashMap();
        map.put("farmId",production.getFarm_id());
        //还原单据之前对存栏变动数和实时存栏数量的改动
        map.put("changeQuantity",0 - production.getChange_quantity());
        farmStockService.updateByFarmId(map);

        /*//todo 生成政府操作记录
        //操作后的数据
        String jsonAfter = JsonUtil.toJsonString(farmRecordsProduction);
        sysLogsService.createLogs(LogsEnum.DELETE,
                FarmRecordsTableEnum.FARM_RECORDS_PRODUCTION.getTableName(),
                farmRecordsProduction.getId().toString(),
                jsonBefore,
                jsonAfter,
                userId);*/

        return con == 0 ? false : true;
    }

    /**
     * 根据前缀寻找表中最大单据号
     * @param prefix
     * @return
     */
    @Override
    public String findCurrentMaxNumber(String prefix) {
        return farmRecordsProductionMapper.findMaxNumber(prefix);
    }

    /**
     * 根据单据类型和单据id更新delete_flag
     *
     * @param paramMapOfUpdateProduction 参数
     */
    @Override
    public void updateDeleteFlagByReportIdAndReportType(Map<String, Object> paramMapOfUpdateProduction) {
        farmRecordsProductionMapper.updateDeleteFlagByReportIdAndReportType(paramMapOfUpdateProduction);
    }
    /**
     * 存栏按数量变化统计
     * @param map
     * @return
     */
    @Override
    public Integer selectQuantityChange(Map map) {
        return farmRecordsProductionMapper.selectQuantityChange(map);
    }

    /**
     * 养殖端按照单据状态分页查询列表
     * @param pageNum
     * @param pageSize
     * @param status
     * @return
     */
    @Override
    public PageInfo<FarmRecordsProduction> selectListByStatus(Integer pageNum, Integer pageSize, Integer status, Long farmId,Integer nonBull) {
        try{
            PageHelper.startPage(pageNum,pageSize);

            Map<String,Object> map = Maps.newHashMap();
            if (status != null){
                map.put("status",status);
            }
            map.put("farm_id",farmId);

            map.put("delete_flag",FarmRecordsNumberStatus.EFFECTIVE.getCode());

            map.put("animal_second_non_bull",nonBull);

            List<FarmRecordsProduction> farmRecordsProductionList = farmRecordsProductionMapper.selectListByStatus(map);

            return new PageInfo<FarmRecordsProduction>(farmRecordsProductionList);
        }catch (Exception e){
            log.error(e.getMessage());
            throw new OPServerException(HttpCode.INTERNAL_SERVER_ERROR,HttpCode.INTERNAL_SERVER_ERROR.getMessage());
        }
    }

    /**
     * 根据养殖场id查询的存栏变动数
     * @param farmId
     * @param breedSecondType
     * @param breedThirdType
     */
    @Override
    public Integer selectQuantityChangeByFarmId(Long farmId,Integer breedSecondType,Integer breedThirdType) {
        Map<String,Object> map = Maps.newHashMap();

        map.put("farm_id",farmId);
        map.put("status",FarmRecordsNumberStatus.SUBMIT.getCode());
        map.put("delete_flag",FarmRecordsNumberStatus.EFFECTIVE.getCode());

        if (breedSecondType != null){
            map.put("breed_second_type",breedSecondType);
        }
        if (breedThirdType != null){
            map.put("breed_third_type",breedThirdType);
        }

        Integer changeQuantity = farmRecordsProductionMapper.selectQuantityChangeByFarmId(map);

        return changeQuantity;
    }

    /**
     * 政府人员根据(二级)畜种查看其管辖区域内 生产单据的合计数
     * @param breedSecondType
     * @param userId
     * @return
     */
    @Override
    public Integer selectQuantityChangeByGovAndBreedType(Long userId, Integer breedSecondType) {
        Map<String,Object> map = Maps.newHashMap();

        map.put("userId",userId);
        map.put("status",FarmRecordsNumberStatus.SUBMIT.getCode());
        map.put("deleteFlag",FarmRecordsNumberStatus.EFFECTIVE.getCode());
        map.put("breedSecondType",breedSecondType);

        Integer quantity = farmRecordsProductionMapper.selectQuantityChangeByGovAndBreedType(map);

        if (quantity == null) {
            quantity = 0;
        }
        return quantity;
    }

    /**
     * 根据日期获取出生,卖出和死淘数
     */
    @Override
    public Map<String,Object> selectQuantityByFarmId(Long farmId, Date startDate, Date endDate) {
        Map<String,Object> map = Maps.newHashMap();
        if (farmId != null) {
            map.put("farmId",farmId);
        }
        if (startDate != null) {
            map.put("startDate",startDate);
        }
        if (endDate != null) {
            map.put("endDate",endDate);
        }
        Map<String,Object> result = farmRecordsProductionMapper.selectQuantityByFarmId(map);
        return result;
    }


    /**
     * 非集中处理无害化对象的创建
     */
    private FarmRecordsHarmlesses createHarmlessesNoCenter(LoginInfo loginInfo, FarmRecordsProduction farmRecordsProduction, Integer isFrom) {
        FarmRecordsHarmlesses farmrecordsHarmlesses = new FarmRecordsHarmlesses();

        farmrecordsHarmlesses.setFarm_id(farmRecordsProduction.getFarm_id());
        farmrecordsHarmlesses.setFarm_name(farmRecordsProduction.getFarm_name());

        farmrecordsHarmlesses.setArea(farmRecordsProduction.getArea());
        farmrecordsHarmlesses.setBreed_type(farmRecordsProduction.getBreed_type());
        farmrecordsHarmlesses.setBreed_second_type(farmRecordsProduction.getBreed_second_type());
        farmrecordsHarmlesses.setBreed_third_type(farmRecordsProduction.getBreed_third_type());
        farmrecordsHarmlesses.setUnit(farmRecordsProduction.getUnit());

        if (farmRecordsProduction.getStable_id() != null) {
            farmrecordsHarmlesses.setStable_id(farmRecordsProduction.getStable_id());
            farmrecordsHarmlesses.setStable_number(farmRecordsProduction.getStable_number());
        }

        //死亡数
        farmrecordsHarmlesses.setQuantity(farmRecordsProduction.getDeath_quantity());

        //死亡原因 ()
        farmrecordsHarmlesses.setDeath_reason(1);

        //默认无害化处理方式是焚烧
        farmrecordsHarmlesses.setTreatment(2);

        //1表示生产死淘过来的，提交后不用做生产死淘 2.表示用户自己填写无害化过来的,需要做生产死淘
        farmrecordsHarmlesses.setIs_from(isFrom);
        farmrecordsHarmlesses.setDate(new Date());

        farmrecordsHarmlesses.setOperator(loginInfo.getRealName());
        farmrecordsHarmlesses.setProvince_id(farmRecordsProduction.getProvince_id());
        farmrecordsHarmlesses.setCity_id(farmRecordsProduction.getCity_id());
        farmrecordsHarmlesses.setRegion_id(farmRecordsProduction.getCity_id());
        farmrecordsHarmlesses.setStreet_id(farmRecordsProduction.getRegion_id());
        farmrecordsHarmlesses.setVillage_id(farmRecordsProduction.getVillage_id());

        farmrecordsHarmlesses.setCreated_at(new Date());
        farmrecordsHarmlesses.setUpdated_at(new Date());

        farmrecordsHarmlesses.setStatus(FarmRecordsNumberStatus.TEMPORARY.getCode());

        return farmrecordsHarmlesses;
    }
}
